package com.csw.shuanfa.utils.id;

import com.csw.shuanfa.utils.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

@RestController
@RequestMapping("IdTest")
@Slf4j
public class IdTest {

    @Autowired
    private SnowFlakeIdUtil snowFlakeIdUtil;

    @Autowired
    private NanoIdUtil nanoIdUtil;
    @Autowired
    private NanoTimeUtil nanoTimeUtil;

    @Autowired
    private RedisIDGenerator redisIDGenerator;

    /**
     * http://localhost:8080/IdTest/test1
     */
    @RequestMapping("test1")
    public void test1() {
        ExecutorService threadPool = ThreadPoolUtil.getExecutorServiceCPU();
        int maxLength = (int) Math.pow(10, 1);
        Long aa = System.nanoTime();
        log.info("进入");
        List<String> idList = new ArrayList<>();
        List<CompletableFuture> futureList = new ArrayList<>();
        //是否重复
        final boolean[] judge = {false};
        try {
            for (int i = 0; i < maxLength; i++) {
                int finalI = i;
                CompletableFuture future = CompletableFuture.supplyAsync(() -> {
                    String id = null;
                    try {
                        //加锁-并发上不去-并发大有问题,需要自定义线程池
                        //id = nanoTimeUtil.getNanoTimeId() + "";//862.6711419526512次/s
                        //加锁-并发大-有问题-并发大有问题,需要自定义线程池
                        //id = nanoTimeUtil.getNanoTimeId2() + "";//725.0155166914612次/s
                        //【赞】雪花
                        //id = snowFlakeIdUtil.nextId() + "";//201825.3080863328次/s
                        //替代uuid
                        //id = nanoIdUtil.getNanoId();//161445.70104808934次/s
                        //【赞】mongodb-objectId
                        //id = objectIdUtil.getObjectId();//178923.94068528226次/s
                        //【赞】-并发大有问题,需要自定义线程池。
                        id = redisIDGenerator.generateId() + "";//31082.82008085698次/s

                    } catch (Exception e) {
                        //log.info("id={}：i={}", id, finalI);
                        throw new RuntimeException(e);
                    }
                    if (String.valueOf(finalI).equals(String.valueOf(maxLength - 1))) {
                        log.info("id={}：i={}", id, finalI);
                    }
//                    if (idList.contains(id)) {
//                        judge[0] = true;
//                        log.info("是否重复1：{}", judge[0]);
//                    }
                    if (id == null) {
                        log.info("id是空：{}", id);
                    }
                    idList.add(id);
                    return null;
                }, threadPool);
                futureList.add(future);
            }
        } catch (Exception e) {
            threadPool.shutdownNow();
        } finally {
            threadPool.shutdown();
        }

        futureList.forEach(a -> {
            try {
                a.get();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        Long bb = System.nanoTime();
        log.info("{}", (maxLength * Math.pow(10, 9) / (bb - aa) + "次/s"));
        log.info("是否重复2：{}", judge[0]);
        //log.info("futureList={}：idList={}", futureList.size(), idList.size());
    }

    /**
     * 用postman并发
     */
    @RequestMapping("test2")
    public void test2() {


        Long aa = System.nanoTime();
        log.info("进入");
        List<String> idList = new ArrayList<>();
        //是否重复
        final boolean[] judge = {false};


        String id = null;

        //加锁-并发上不去-并发大有问题,需要自定义线程池
        //id = nanoTimeUtil.getNanoTimeId() + "";//862.6711419526512次/s
        //加锁-并发大-有问题-并发大有问题,需要自定义线程池
        //id = nanoTimeUtil.getNanoTimeId2() + "";//725.0155166914612次/s
        //【赞】雪花
        //id = snowFlakeIdUtil.nextId() + "";//201825.3080863328次/s
        //替代uuid
        //id = nanoIdUtil.getNanoId();//161445.70104808934次/s
        //【赞】mongodb-objectId
        //id = objectIdUtil.getObjectId();//178923.94068528226次/s
        //【赞】-并发大有问题,需要自定义线程池。
        id = redisIDGenerator.generateId() + "";//31082.82008085698次/s


//                    if (idList.contains(id)) {
//                        judge[0] = true;
//                        log.info("是否重复1：{}", judge[0]);
//                    }
        if (id == null) {
            log.info("id是空：{}", id);
        }
        idList.add(id);


        Long bb = System.nanoTime();
        log.info("{}", (1 * Math.pow(10, 9) / (bb - aa) + "次/s"));
        log.info("是否重复2：{}", judge[0]);
        //log.info("futureList={}：idList={}", futureList.size(), idList.size());

    }
}
